/*
   Copyright (c) [2023] [魔凤啸天]
   [MFUI] is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2. 
   You may obtain a copy of Mulan PSL v2 at:
            http://license.coscl.org.cn/MulanPSL2 
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.  
   See the Mulan PSL v2 for more details.  
*/
#pragma once
#include<SDL2/SDL_ttf.h>
#include "core.hpp"
#include<string>

namespace MFUI{
	inline unsigned int utf8len(unsigned char t){
		static const unsigned int lengths[] = {
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0
		};
		return lengths[t >> 3];
	}
	extern const std::string emptytext;
	size_t utilreplace(std::string& src,const std::string& target,const std::string& t,size_t n);
	//调用者保证参数合法
	void utilreplace(std::string& src,size_t begin,size_t end,const char* t);
	void utilreplacestring(std::string& src,size_t begin,size_t end,const std::string& t);
	//移动选区内容 调用者保证参数合法(pos<begin|end<pos)
	void utilmoveleft(std::string& src,size_t begin,size_t end,size_t pos);
	//移动选区内容 调用者保证参数合法(pos<begin|end<pos)
	void utilmoveright(std::string& src,size_t begin,size_t end,size_t pos);
	class Font{
		struct Cache{
			std::unordered_map<std::string,SDL_Texture*> words;

			~Cache();
		};
		std::unordered_map<int,Cache*> cache;

		protected:
		TTF_Font* font;
		SDL_Texture* buildcache(Renderer* r,const char* begin,const char* end,int fontsize);

		public:
		struct TextUnit{
			size_t begin;
			unsigned int length;
			float beginpos;

			TextUnit(size_t begin,unsigned int length,float beginpos):begin(begin),
			length(length),beginpos(beginpos){}
		};

		//f仅引用，自行管理内存
		Font(TTF_Font* f);
		~Font();
		void removecache(int fontsize);
		void setfont(TTF_Font* f);
		//水平排列 超出dst.w或碰到0时后停止渲染
		void hdraw(Renderer* r,const SDL_FRect& dst,const std::string& text,int fontsize,
		SDL_Color color,bool cuttail=false);
		//水平排列 超出dst.w或碰到0时停止渲染 返回下一次的起始点
		void hdraw(Renderer* r,const SDL_FRect& dst,const char* begin,const char* end,int fontsize,
		SDL_Color color,bool cuttail=false);
		//水平排列 超出dst.w或碰到0时停止渲染 返回下一次的起始点
		const char* hdraw(Renderer* r,const SDL_FRect& dst,const char* begin,const char* end,int fontsize,
		SDL_Color color,float& outw,float& outh);
		//仅修改w和h
		void hsize(const SDL_FRect& dst,const std::string& text,int fontsize,SDL_FRect& out);
		//仅修改w和h
		const char* hsize(const SDL_FRect& dst,const char* begin,const char* end,int fontsize,SDL_FRect& out);
		//仅修改w和h
		void hsize(const std::string& text,int fontsize,SDL_FRect& out);
		//仅修改w和h
		void hsize(const char* begin,const char* end,int fontsize,SDL_FRect& out);
		//units=单个字的信息(size+1个 位置从0开始计算)
		void htextunits(const std::string& text,int fontsize,std::vector<TextUnit>& units);
		//units=单个字的信息(size+1个 位置从0开始计算)
		void htextunits(const char* begin,const char* end,int fontsize,std::vector<TextUnit>& units);
		int height(int fontsize);
	};
	class TextNodeBase{
		protected:
		std::string text;
		SDL_Color background,textcolor;
		Font* font;//仅引用 自行管理
		int fontsize;
		SDL_FRect textrect;
		Align align;

		TextNodeBase(const std::string& text,Font* font,int fontsize,
		SDL_Color textcolor,SDL_Color background,Align align);
		void _tryrendertext(Renderer* r,SDL_FRect* rect);
		//背景相关
		virtual void _updatebase()=0;
		virtual void _updatetext()=0;
		public:
		void settext(const std::string& text);
		const std::string& gettext()const;
		void settextcolor(SDL_Color color);
		SDL_Color gettextcolor()const;
		void setbackground(SDL_Color color);
		SDL_Color getbackground()const;
		void setfontsize(int size);
		int getfontsize()const;
		void setfont(Font* font);
		Font* getfont()const;
		void setalign(Align align);
		Align getalign()const;
	};
}